#ifndef SVIDEOWIDGET_H
#define SVIDEOWIDGET_H

#include <QWidget>
#include <QMediaPlayer>
#include <QMap>
#include <mutex>

namespace Ui {
class SVideoWidget;
}

/*
    继承了 QWidget GUI类
    整体功能:
        作为音视频的widget类，实现了音乐播放和视频播放的载体，通过QMediaPlayer解析音视频文件，
    其中音乐名称、歌手、专辑名称、专辑图片等信息由自定义ID3解析器多线程解析，相关实现在ToolUtils，音乐帧数据由QMediaPlayer解析；
    其中视频帧数据由QMediaPlayer解析并发给自定义OpenGLWidget类进行绘制.其余相关功能通过内置的QMediaPlayer
    实现(如: 播放/暂停、总时间、音量大小、播放速率、播放方式<顺序、循环...>)
*/

class SVideoWidget : public QWidget
{
    Q_OBJECT

public:
    explicit SVideoWidget(QString filePath, QWidget* parent = nullptr);
    ~SVideoWidget();

    // 相关辅助函数
    QMediaPlayer* Player();
    qint64 GetTotalTime();
    qint64 GetCurrentTime();
    qreal GetRate();
    QUrl GetUrl();
    float GetVolume();
    bool IsPlaying();
    bool IsLoop();
    QString PlayerType();

protected:
    // 重载了paintEvent函数，实现了播放音乐时背景图片的展示
    void paintEvent(QPaintEvent *event) override;

signals:
    // 信号: 作用于多线程解析MP3源文件获取到相关信息后emit
    void LoadMp3DataFinished();
    // 信号: 播放或暂停等status改变时emit
    void PlayerStatusChanged(bool isPlaying);
    // 信号: 播放帧改变时emit
    void PlayerPositionChanged(qint64 position);
    // 信号: 播放方式改变时emit
    void PlayerLoopChanged(bool isLoop);
    // 信号: 播放音量大小改变时emit
    void PlayerVolumeChanged(float volume);
    // 信号: 播放文件改变时emit
    void PlayerSourceChanged(const QUrl &media);

public slots:
    // 槽: 控制播放和暂停
    void PlayOrPause();
    // 槽: 设置播放帧的位置(相当于改变进度条)
    void SetPlayerPosition(qint64 position);
    // 槽: 改变播放方式
    void ChangePlayerLoop();
    // 槽: 改变播放音量大小
    void SetPlayerVolume(float volume);
    // 槽: 设置播放速率
    void SetPlayerRate(qreal rate);

private slots:
    // 槽: 加载UI相关工作,用于emit LoadMp3DataFinished 之后
    void LoadUi();
    // 槽: 关联QMediaPlayer的信号,执行emit PlayerStatusChanged
    // 以下私有槽同理
    void DoPlayingChanged(bool isPlaying);
    // position 以ms为单位
    void DoPlayPostionChnaged(qint64 position);
    void DoPlayerLoopChanged();
    void DoPlayerVolumeChanged(float volume);
    void DoPlayerSourceChanged(const QUrl &media);

private:
    void Init();

    Ui::SVideoWidget* ui;
    QString mFilePath;
    QMediaPlayer* mPlayer;
    QString mPlayerType;
    std::mutex mMutex;
    // 专辑图片
    QImage mAlbumImage;
    // 高斯模糊后专辑背景图
    QImage mBackgroundImage;
    // 其他音乐相关信息
    QMap<QString, QString> mOtherMusicInfo{};
    bool mLoadFinished{false};
};

#endif // SVIDEOWIDGET_H
